using System;
using System.Linq;
using Core;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Modules.Animation
{
    public class AnimationSubsystem : GameSubsystem
    {
        [SerializeField] private AnimProxyWrapper[] animProxies;
        
        public AnimatorProxy[] GetAnimProxies(string[] labels)
        {
            return animProxies.Where(wrapper => labels.Contains(wrapper.Label)).Select(wrapper => wrapper.Proxy).ToArray();
        }

        public AnimatorProxy[] GetAnimProxiesByGroup(string group)
        {
            return animProxies.Where(a => a.Group.Equals(group)).Select(a => a.Proxy).ToArray();
        }

        public AnimatorProxy[] GetAllAnimProxies()
        {
            return animProxies.Select(a => a.Proxy).ToArray();
        }

        public AnimatorProxy GetAnimProxy(string label)
        {
            return animProxies.First(wrapper => wrapper.Label.Equals(label)).Proxy;
        }

        public float PlayByGroup(string group, string stateName)
        {
            return GetAnimProxiesByGroup(group).Select(proxy => proxy.Play(stateName)).Max();
        }

        public float PlayByLabels(string[] labels, string stateName)
        {
            return GetAnimProxies(labels).Select(proxy => proxy.Play(stateName)).Max();
        }

        public float PlayByLabel(string label, string stateName)
        {
            return GetAnimProxy(label).Play(stateName);
        }

        public float PlayAll(string stateName)
        {
            return GetAllAnimProxies().Select(proxy => proxy.Play(stateName)).Max();
        }

        public void SetPosByLabel(string label, string stateName, float position)
        {
            GetAnimProxy(label).SetPos(stateName, position);
        }


        public void SetPosByLabels(string[] labels, string stateName, float position)
        {
            foreach (AnimatorProxy proxy in GetAnimProxies(labels))
            {
                proxy.SetPos(stateName, position);
            }
        }

        public void SetPosByGroup(string group, string stateName, float position)
        {
            foreach (AnimatorProxy proxy in GetAnimProxiesByGroup(group))
            {
                proxy.SetPos(stateName, position);
            }
        }

        public void SetAllPos(string stateName, float position)
        {
            foreach (var proxy in GetAllAnimProxies())
            {
                proxy.SetPos(stateName, position);
            }
        }
    }

    [Serializable]
    public class AnimProxyWrapper
    {
        [HorizontalGroup("info", LabelWidth = 40, PaddingRight = 5)] [SerializeField]
        private string label;

        [HorizontalGroup("info", LabelWidth = 40)] [SerializeField]
        private string group;

        [SerializeField] [HorizontalGroup(LabelWidth = 40)]
        private AnimatorProxy proxy;

        public string Group => group;
        public string Label => label;

        public AnimatorProxy Proxy => proxy;
    }
}